Repeating plots by a factor

Elizabeth King
Kevin Middleton

Getting more information into a plot

  • Aesthetics only go so far
    • More than about 2 becomes unwieldy
  • Dodging and faceting can provide more options

Bear movement

Black bear movements in northern Minnesota 1

tibble [2,768 × 9] (S3: tbl_df/tbl/data.frame)
 $ log_Move : num [1:2768] 2.939 0.525 -0.596 -0.375 -0.639 ...
 $ Heartrate: int [1:2768] 60 54 34 37 37 41 44 55 58 51 ...
 $ Season   : Factor w/ 3 levels "Fall","Spring",..: 2 2 2 2 2 2 2 2 2 2 ...
 $ DayNight : Factor w/ 2 levels "Day","Night": 1 1 1 1 1 1 1 1 1 1 ...
 $ Sex      : Factor w/ 2 levels "F","M": 1 1 1 1 1 1 1 1 1 1 ...
 $ Stage    : Factor w/ 3 levels "CubPrep","Fem",..: 2 2 2 2 2 2 2 2 2 2 ...
 $ Day      : int [1:2768] 96 97 99 102 103 104 105 107 108 110 ...
 $ BearID   : Factor w/ 7 levels "4011","4021",..: 2 2 2 2 2 2 2 2 2 2 ...
 $ Year     : int [1:2768] 2010 2010 2010 2010 2010 2010 2010 2010 2010 2010 ...

Aggregate bear movement data

BearID Season DayNight Year n
4011 Fall Day 2012 44
4011 Fall Night 2012 44
4011 Spring Day 2012 38
4011 Spring Night 2012 47
4011 Summer Day 2012 50
4011 Summer Night 2012 52
4021 Fall Day 2010 32
4021 Fall Day 2012 56
4021 Fall Night 2010 7
4021 Fall Night 2012 56
4021 Spring Day 2010 47
4021 Spring Day 2012 64
4021 Spring Night 2010 24
4021 Spring Night 2012 64
4021 Summer Day 2010 44
4021 Summer Day 2012 59
4021 Summer Night 2010 38
4021 Summer Night 2012 59
4041 Fall Day 2009 15
4041 Fall Night 2009 6
4041 Spring Day 2009 71
4041 Spring Night 2009 34
4041 Summer Day 2009 41
4041 Summer Night 2009 24
4055 Fall Day 2012 51
4055 Fall Night 2012 51
4055 Spring Day 2010 60
4055 Spring Day 2012 93
4055 Spring Night 2010 44
4055 Spring Night 2012 91
4055 Summer Day 2010 37
4055 Summer Day 2012 62
4055 Summer Night 2010 28
4055 Summer Night 2012 62
4083 Fall Day 2012 60
4083 Fall Night 2012 60
4083 Spring Day 2012 66
4083 Spring Night 2012 66
4083 Summer Day 2012 62
4083 Summer Night 2012 61
4085 Fall Day 2012 67
4085 Fall Night 2012 66
4085 Spring Day 2012 92
4085 Spring Night 2012 91
4085 Summer Day 2012 62
4085 Summer Night 2012 61
4087 Fall Day 2012 36
4087 Fall Night 2012 41
4087 Spring Day 2012 89
4087 Spring Night 2012 80
4087 Summer Day 2012 57
4087 Summer Night 2012 56

Dodging points

  • Use the position argument to shift a group.
    • Set width by trial and error
  • Often used with color
ggplot(bear,
       aes(x = BearID,
           y = log_Move,
           color = DayNight,
           group = DayNight)) +
  geom_point(position = position_dodge(width = 0.2))

Dodging points

Dodging points with jitter

  • Use position = position_jitterdodge
  • Also set seed to make the jitter reproducible
ggplot(bear,
       aes(x = BearID,
           y = log_Move,
           color = DayNight,
           group = DayNight)) +
  geom_point(position = position_jitterdodge(jitter.width = 0.15,
                                             dodge.width = 0.3,
                                             seed = 34683))

Dodging points with jitter

Dodging points with jitter

Further refinements:

  • Add alpha to reduce overplotting
ggplot(bear,
       aes(x = BearID,
           y = log_Move,
           color = DayNight,
           group = DayNight)) +
  geom_point(position = position_jitterdodge(jitter.width = 0.15,
                                             dodge.width = 0.3,
                                             seed = 34683),
             alpha = 0.25)

Dodging points with jitter

Dodging bar graphs

width = 0.9 leaves no space between bars but leaves space between BearIDs.

bear |> 
  group_by(BearID, Season) |> 
  summarize(Mean_log_Move = mean(log_Move),
            .groups = "drop") |> 
  ggplot(aes(x = BearID,
             y = Mean_log_Move,
             fill = Season,
             group = Season)) +
  geom_bar(stat = "identity",
           position = position_dodge(width = 0.9))

Dodging bar graphs

Faceting

Good for focusing on comparisons among measurements

  • Automated generation of multiple plots, each split by the levels of a factor
  • By wrapping in factor order with facet_wrap()
  • By rows or columns with facet_grid(), if there is some logical order
    • Think about the direction of the comparison (down rows or across columns) and the way your eyes will move around the plot

Faceting in rows

. is a placeholder for faceting only by row or column

Facet in rows by Season:

ggplot(bear,
       aes(x = BearID,
           y = log_Move,
           color = DayNight,
           group = DayNight)) +
  geom_point(position = position_jitterdodge(jitter.width = 0.15,
                                             dodge.width = 0.3,
                                             seed = 34683),
             alpha = 0.25) +
  facet_grid(Season ~ .)

Faceting in rows

Faceting in columns

ggplot(bear,
       aes(x = BearID,
           y = log_Move,
           color = DayNight,
           group = DayNight)) +
  geom_point(position = position_jitterdodge(jitter.width = 0.15,
                                             dodge.width = 0.3,
                                             seed = 34683),
             alpha = 0.25) +
  facet_grid(. ~ Season)

Faceting in columns

Faceting in rows and columns

ggplot(bear,
       aes(x = BearID,
           y = log_Move,
           color = DayNight,
           group = DayNight)) +
  geom_point(position = position_jitterdodge(jitter.width = 0.15,
                                             dodge.width = 0.3,
                                             seed = 34683),
             alpha = 0.25) +
  facet_grid(Season ~ DayNight)

Faceting in rows and columns

Wrapping facets

Number of rows (nrow) or columns (ncol) can be specified

Wrapping by BearID with facet_wrap():

ggplot(bear,
       aes(x = Season,
           y = log_Move,
           color = DayNight,
           group = DayNight)) +
  geom_point(position = position_jitterdodge(jitter.width = 0.15,
                                             dodge.width = 0.3,
                                             seed = 34683),
             alpha = 0.25) +
  facet_wrap("BearID")

Wrapping facets

Axis ranges

  • By default, all axis ranges are equal (fixed)
    • Usually the behavior you want
  • free_x, free_y, and free can be used to allow x, y, or both axes to vary by facet.
    • Useful for making composite plots in one plot statement
    • Variables with different magnitudes or ranges

Pivoting the bear data

bear_long <- bear |> 
  select(Season, log_Move, Heartrate, BearID) |> 
  pivot_longer(cols = c(log_Move, Heartrate),
               names_to = "Measurement")
bear_long
# A tibble: 5,536 × 4
   Season BearID Measurement  value
   <fct>  <fct>  <chr>        <dbl>
 1 Spring 4021   log_Move     2.94 
 2 Spring 4021   Heartrate   60    
 3 Spring 4021   log_Move     0.525
 4 Spring 4021   Heartrate   54    
 5 Spring 4021   log_Move    -0.596
 6 Spring 4021   Heartrate   34    
 7 Spring 4021   log_Move    -0.375
 8 Spring 4021   Heartrate   37    
 9 Spring 4021   log_Move    -0.639
10 Spring 4021   Heartrate   37    
# … with 5,526 more rows

Default equal axis scale

ggplot(bear_long,
       aes(x = BearID,
           y = value)) +
  geom_point(position = position_jitter(width = 0.2,
                                        seed = 4527345),
             alpha = 0.25) +
  facet_grid(Measurement ~ Season)

Default equal axis scale

With free axis scale

ggplot(bear_long,
       aes(x = BearID,
           y = value)) +
  geom_point(position = position_jitter(width = 0.2,
                                        seed = 4527345),
             alpha = 0.25) +
  facet_grid(Measurement ~ Season, scales = "free_y")

With free axis scale